package leetcode.level2;

import static utils.Tool.pt;

/**
 * 622. 设计循环队列(FIFO（先进先出）)
 * @author ben
 * @date 2021-10-27 11:15:51 CST
 */
/*
 * 成绩：
 * 执行用时：4 ms , 在所有 Java 提交中击败了 100.00% 的用户
内存消耗：39.2 MB , 在所有 Java 提交中击败了 9.49% 的用户
 */
public class MyCircularQueue622 {

	public static void main(String[] args) {
//		MyCircularQueue circularQueue = new MyCircularQueue(3);
//		pt("入队：");
//		pt(circularQueue.enQueue(1));
//		pt(circularQueue);
//		circularQueue.debug();
//		pt(circularQueue.enQueue(2));
//		pt(circularQueue);
//		circularQueue.debug();
//		pt(circularQueue.enQueue(3));
//		pt(circularQueue);
//		circularQueue.debug();
//		pt(circularQueue.enQueue(4));
//		pt(circularQueue);
//		circularQueue.debug();
//		
//		pt("\n出队：");
//		pt(circularQueue.deQueue());
//		pt(circularQueue);
//		circularQueue.debug();
//		pt(circularQueue.deQueue());
//		pt(circularQueue);
//		circularQueue.debug();
//		pt(circularQueue.deQueue());
//		pt(circularQueue);
//		circularQueue.debug();
//		pt(circularQueue.deQueue());
//		pt(circularQueue);
//		circularQueue.debug();
//		pt(circularQueue.deQueue());
//		pt(circularQueue);
//		circularQueue.debug();
//		
//		pt();
		
		MyCircularQueue circularQueue = new MyCircularQueue(3);
		pt(circularQueue.enQueue(1));
		pt(circularQueue.enQueue(2));
		pt(circularQueue.enQueue(3));
		pt(circularQueue.enQueue(4));
		pt(circularQueue.Rear());
		pt(circularQueue.isFull());
		pt(circularQueue.deQueue());
		pt(circularQueue.enQueue(4));
		pt(circularQueue.Rear());

	}

}

class MyCircularQueue {

	private int k;
	private int[] data;
	
	private int start = -1;
	private int end = -1;
	
	private boolean ffull = false;
	private boolean fempty = true;
	
    public MyCircularQueue(int k) {
    	this.k = k;
    	this.data = new int[k];
    }
    
    public boolean enQueue(int value) {
    	if (ffull) {
    		return false;
    	}
    	
    	// next position
    	int t1 = -1;
    	if (start < 0) {
    		t1 = start + 1;
    	} else {
    		t1 = start;
    	}
    	int t1mod = t1 % k;
    	
    	this.data[t1mod] = value;
    	
    	this.start = (t1mod + 1) % k;
    	
    	if (this.end == -1) {
    		this.end = 0;
    	}
    	
    	if (this.start == this.end) {
    		ffull = true;
    	}
		fempty = false;
    	
    	return true;
    }
    
    public boolean deQueue() {
    	if (fempty) {
    		return false;
    	} else {
    		this.end = (this.end + 1) % k;
    		if (this.end == this.start) {
    			this.fempty = true;
    		}
    		
			this.ffull = false;
    	}
    	
    	return true;
    }
    
    public int Front() {
    	if (fempty) {
    		return -1;
    	}
    	
    	return this.data[this.end];
    }
    
    public int Rear() {
    	if (fempty) {
    		return -1;
    	}
    	
    	int idx = this.start - 1;
    	if (idx == -1) {
    		idx = (k - 1);
    	}
    	
    	return this.data[idx];
    }
    
    public boolean isEmpty() {
    	return fempty;
    }
    
    public boolean isFull() {
    	return ffull;
    }
    
    public String toString() {
    	return "k=" + k + ", start=" + start + ", end=" + end 
    			+ ", ffull=" + ffull + ", fempty=" + fempty;
    }
    
    public void debug() {
    	System.out.print("debug: ");
    	for (int i=0; i<this.data.length; i++) {
    		System.out.print(this.data[i] + " ");
    	}
    	pt();
    }
}